/*
 * MainFrame.java
 *
 * Created on Penktadienis, 2006, Spalio 6, 13.11
 *
 */

package org.mif.mobp.gui;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.prefs.Preferences;

/**
 * 
 */
public class MainFrame extends JFrame implements SettingsSaver {
    public static final String APP_NAME = "MP";
    
    private JToolBar toolbar;
    private JMenuBar menubar;
    
    protected Action  exitAction, 
                      openAction,
                      optionsAction,
                      aboutAction,
                      watchAction,
                      stopAction;
    
    protected MapPainter map;
    protected JScrollPane scroll;
    protected JLabel statusBar;
    
    protected WatchControl wc;
    
    protected Preferences p;
    
    /** Creates a new instance of MainFrame */
    public MainFrame() {
        super (APP_NAME);
        p = Preferences.userRoot().node("mobp");
        setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        addWindowListener(new WindowAdapter () {
            public void windowClosing (WindowEvent event) {
                saveSettings ();
                setVisible (false);
                System.exit (0);
            }
        });
        scroll = new JScrollPane ();
        add (scroll, BorderLayout.CENTER);
        statusBar = new JLabel (" ");
        add (statusBar, BorderLayout.SOUTH);
        
        createActions();
        createToolBar();
        createMenuBar();
        
        pack();
        restoreSettings();
        setVisible (true);
    }
    
    private void createActions () {
        exitAction = new AbstractAction () {
            {
                putValue (NAME, "Exit");
                putValue (SHORT_DESCRIPTION, "Close the application");
                putValue (MNEMONIC_KEY, KeyEvent.VK_X);
                putValue (ACTION_COMMAND_KEY, "exitAction");
                putValue (SMALL_ICON, createImageIcon ("images/exit.png"));
            }  
            public void actionPerformed (ActionEvent ae) {
                saveSettings ();
                System.exit(0);
            }
        };
        openAction = new AbstractAction () {
            {
                putValue (NAME, "Open map");
                putValue (SHORT_DESCRIPTION, "Open map");
                putValue (MNEMONIC_KEY, KeyEvent.VK_O);
                putValue (ACTION_COMMAND_KEY, "openAction");
                putValue (SMALL_ICON, createImageIcon ("images/open.png"));
            }
            public void actionPerformed (ActionEvent ae) {
                String path = p.get("PathToMapDirectory", "");
                final JFileChooser fc = new JFileChooser (path);
                fc.setFileFilter(new javax.swing.filechooser.FileFilter() {
                    public boolean accept (java.io.File file) {
                        if (file.isDirectory())
                            return true;
                        if (file.getName().endsWith(".xml") || file.getName().endsWith(".XML"))
                            return true;
                        return false;
                    }
                    public String getDescription () {
                        return "Map XML files";
                    }
                });
                int value = fc.showOpenDialog(MainFrame.this);
                if (value == JFileChooser.APPROVE_OPTION) {
                    java.io.File file = fc.getSelectedFile ();
                    p.put ("PathToMap", file.getAbsolutePath());
                    p.put("PathToMapDirectory", file.getParent());
                    remove (scroll);
                    try {
                        map = new MapPainter (p.get("PathToMap", ""));
                        map.addPropertyChangeListener("coordinates", new java.beans.PropertyChangeListener() {
                            public void propertyChange(PropertyChangeEvent evt) {
                                Object o = evt.getNewValue();
                                statusBar.setText(o.toString());
                            }
                        });
                    }
                    catch (IllegalArgumentException ex) {
                        JOptionPane.showMessageDialog(MainFrame.this, ex.getMessage());
                    }
                    scroll = new JScrollPane (map);
                    add (scroll, BorderLayout.CENTER);
                    validate(); //atnaujinam fraima
                    watchAction.setEnabled(true);
                }
            }
        };
        optionsAction = new AbstractAction () {
            {
                putValue (NAME, "Options");
                putValue (SHORT_DESCRIPTION, "Options dialog");
                putValue (MNEMONIC_KEY, KeyEvent.VK_O);
                putValue (ACTION_COMMAND_KEY, "optionsAction");
                putValue (SMALL_ICON, createImageIcon ("images/options.png"));
            }
            public void actionPerformed (ActionEvent e) {
                if (wc != null) { 
                    if (wc.isStarted())
                        wc.stop();
                    watchAction.setEnabled(true);
                    stopAction.setEnabled(false);
                }
                OptionsDialog od = new OptionsDialog (MainFrame.this);
                try {
                    org.mif.mobp.core.DriversObjectFactory.initialize(p.getBoolean("IsPort",false), 
                        p.getBoolean("IsPort",false) ? p.get("PortName", "COM1") : p.get("EnteredPath", ""),
                        p.get("SelectedDriverName", "org.mif.mobp.gps"));
                }
                catch (RuntimeException ex) {
                    System.out.println (ex.getMessage());
                }
            }
        };
        aboutAction = new AbstractAction () {
            {
                putValue (NAME, "About");
                putValue (SHORT_DESCRIPTION, "About dialog");
                putValue (MNEMONIC_KEY, KeyEvent.VK_A);
                putValue (ACTION_COMMAND_KEY, "aboutAction");
                putValue (SMALL_ICON, createImageIcon ("images/about.png"));
            }
            public void actionPerformed (ActionEvent ae) {
                JOptionPane.showMessageDialog(MainFrame.this, "Mobiliuju paslaugu projektas.\n" +
                        "Autoriai:\nVitalijus Vidinevicius\nEugenijus Medelis\n");
            }
        };
        
        watchAction = new AbstractAction () {
            {
                putValue (NAME, "Watch");
                putValue (SHORT_DESCRIPTION, "Watch the object");
                putValue (MNEMONIC_KEY, KeyEvent.VK_W);
                putValue (ACTION_COMMAND_KEY, "watchAction");
                putValue (SMALL_ICON, createImageIcon ("images/watch.png"));
            }
            public void actionPerformed (ActionEvent ae) {
                try {    
                    checkParameters();
                    try {
                        execute ();
                    }
                    catch (RuntimeException ex) {
                        JOptionPane.showMessageDialog(MainFrame.this, ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
                        return;
                    }
                    stopAction.setEnabled(true);
                    setEnabled(false);
                }
                catch (IllegalArgumentException ex) {
                    JOptionPane.showMessageDialog(MainFrame.this, ex.getMessage());
                }
            }
        };
        
        stopAction = new AbstractAction () {
            {
                putValue (NAME, "Stop Watch");
                putValue (SHORT_DESCRIPTION, "Stop watching the object");
                putValue (MNEMONIC_KEY, KeyEvent.VK_S);
                putValue (ACTION_COMMAND_KEY, "stopWatch");
                putValue (SMALL_ICON, createImageIcon ("images/stop.png"));
            }
            public void actionPerformed (ActionEvent ae) {
                if (wc.isStarted())
                    wc.stop();
                watchAction.setEnabled(true);
                setEnabled(false);
            }
        };
    }
    
    private void createToolBar () {
        toolbar = new JToolBar ("Main Toolbar");
        
        JButton exitButton = new JButton (exitAction);
        exitButton.setText("");
        toolbar.add (exitButton);
        
        JButton openButton = new JButton (openAction);
        openButton.setText("");
        toolbar.add (openButton);
        
        JButton watchButton = new JButton (watchAction);
        watchButton.setText("");
        toolbar.add (watchButton);
        watchAction.setEnabled(false);
        
        JButton stopButton = new JButton (stopAction);
        stopButton.setText("");
        toolbar.add (stopButton);
        stopAction.setEnabled(false);
        
        JButton optionsButton = new JButton (optionsAction);
        optionsButton.setText("");
        toolbar.add (optionsButton);
        
        
        add (toolbar, BorderLayout.NORTH);
    }
    
    private void createMenuBar () {
        menubar = new JMenuBar ();
        
        JMenu fileMenu = new JMenu ("File");
        fileMenu.setMnemonic(KeyEvent.VK_F);
        
        JMenuItem openMenuItem = new JMenuItem (openAction);
        openMenuItem.setMnemonic(KeyEvent.VK_O);
        
        JMenuItem exitMenuItem = new JMenuItem (exitAction);
        exitMenuItem.setMnemonic(KeyEvent.VK_X);
        
        fileMenu.add (openMenuItem);
        fileMenu.add (exitMenuItem);
        
        JMenu aboutMenu = new JMenu ("About");
        aboutMenu.setMnemonic (KeyEvent.VK_A);
        
        JMenuItem aboutMenuItem = new JMenuItem (aboutAction);
        aboutMenuItem.setMnemonic (KeyEvent.VK_A);
        aboutMenu.add (aboutMenuItem);
        
        
        menubar.add (fileMenu);
        menubar.add (Box.createHorizontalGlue());
        menubar.add (aboutMenu);
        setJMenuBar(menubar);
    }
    
    
    
    public static ImageIcon createImageIcon (String path) {
        java.net.URL url = MainFrame.class.getResource (path);
        if (url != null)
            return new ImageIcon (url);
        else 
            return null;
    }
    
    public void restoreSettings () {
        AppProperties properties = AppProperties.getInstance();
        properties.getSizePos(this.getClass().getName(), (Component)this);
    }
    
    public void saveSettings () {
        AppProperties properties = AppProperties.getInstance();
        properties.putSizePos(this.getClass().getName(), (Component)this);
    }
    
    //tikrina ar viskas gerai su parametrais
    private void checkParameters () {
        if (p.get("PathToMap", "").equals(""))
            throw new IllegalArgumentException ("Choose the map");
        java.io.File f = new java.io.File (p.get("PathToMap", ""));
        if (!f.canRead())
            throw new IllegalArgumentException ("Can not read map file");
        if ((p.get("EnteredPath", "")).equals(""))
            throw new IllegalArgumentException ("File name is missing");
    }
    
    //Cia paleisim visa procesa
    private void execute () {
        wc = new WatchControl ();
        wc.start(map);
    }
}
